Модуль
======

Модуль — это самодостаточная программная единица, состоящая из [моделей](/doc/guide/basics.model), [представлений](/doc/guide/basics.view), [контроллеров](/doc/guide/basics.controller) и иных компонентов.
Во многом модуль схож с [приложением](/doc/guide/basics.application).
Основное различие заключается в том, что модуль не может использоваться сам по себе — только в составе приложения.
Пользователи могут обращаться к контроллерам внутри модуля абсолютно так же, как и в случае работы с обычными контроллерами приложения.

Модули могут быть полезными в нескольких ситуациях. Если приложение очень объёмное, мы можем разделить его на несколько модулей, разрабатываемых и
поддерживаемых по отдельности. Кроме того, некоторый часто используемый функционал, например, управление пользователями, комментариями и пр.,
может разрабатываться как модули, чтобы впоследствии можно было с лёгкостью воспользоваться им вновь.


Создание модуля
---------------

Модуль организован как директория, имя которой выступает в качестве уникального [идентификатора модуля|CWebModule::id]. Структура директории
модуля похожа на структуру [базовой директории приложения](/doc/guide/basics.application#application-base-directory). Ниже представлена
типовая структура директории модуля с именем `forum`:

~~~
forum/
   ForumModule.php            файл класса модуля
   components/                содержит пользовательские компоненты
      views/                  содержит файлы представлений для виджетов
   controllers/               содержит файлы классов контроллеров
      DefaultController.php   файл класса контроллера по умолчанию
   extensions/                содержит сторонние расширения
   models/                    содержит файлы классов моделей
   views/                     содержит файлы представлений контроллера и макетов
      layouts/                содержит файлы макетов
      default/                содержит файлы представлений для контроллера по умолчанию
         index.php            файл представления 'index'
~~~

В корневой директории модуля должен находиться класс модуля, наследующий [CWebModule]. Имя класса определяется, используя выражение
`ucfirst($id).'Module'`, где `$id` соответствует идентификатору модуля (или названию директории модуля). Класс модуля выполняет роль
центрального хранилища информации, совместно используемой компонентами модуля. Например, мы можем использовать
[CWebModule::params] для хранения параметров модуля, а также [CWebModule::components] для совместного использования
[компонентов приложения](/doc/guide/basics.application#application-component) на уровне модуля.

> Tip|Подсказка: Для создания базового каркаса модуля можно воспользоваться
> генератором модулей, входящим в состав Gii.


Использование модуля
--------------------

Для использования модуля необходимо поместить папку модуля в директорию `modules`
[базовой директории приложения](/doc/guide/basics.application#application-base-directory). Далее необходимо объявить
идентификатор модуля в свойстве приложения [modules|CWebApplication::modules]. Например, чтобы воспользоваться модулем `forum`,
приведённым выше, можно использовать следующую [конфигурацию приложения](/doc/guide/basics.application#application-configuration):

~~~
[php]
return array(
	…
	'modules'=>array('forum',…),
	…
);
~~~

Кроме того, модулю можно задать начальные значения свойств. Порядок использования такой же, как и с [компонентами
приложения](/doc/guide/basics.application#application-component). Например, модуль `forum` может иметь в своём классе свойство с именем
`postPerPage`, которое может быть установлено в [конфигурации приложения](/doc/guide/basics.application#application-configuration)
следующим образом:

~~~
[php]
return array(
	…
	'modules'=>array(
	    'forum'=>array(
	        'postPerPage'=>20,
	    ),
	),
	…
);
~~~

К экземпляру модуля можно обращаться посредством свойства [module|CController::module] активного в настоящий момент контроллера. Через экземпляр
модуля можно получить доступ к совместно используемой информации на уровне модуля. Например, для того чтобы обратиться к упомянутому выше свойству
`postPerPage`, мы можем воспользоваться следующим выражением:

~~~
[php]
$postPerPage=Yii::app()->controller->module->postPerPage;
// или таким, если $this ссылается на экземпляр контроллера
// $postPerPage=$this->module->postPerPage;
~~~

Обратиться к действию контроллера в модуле можно, используя [маршрут](/doc/guide/basics.controller#route) `moduleID/controllerID/actionID`.
Например, предположим, что всё тот же модуль `forum` имеет контроллер с именем `PostController`. Тогда мы можем использовать
[маршрут](/doc/guide/basics.controller#route) `forum/post/create` для того, чтобы обратиться к действию `create` этого контроллера.
Адрес URL, соответствующий этому маршруту, будет таким: `http://www.example.com/index.php?r=forum/post/create`.

> Tip|Подсказка: Если контроллер находится в подпапке папки `controllers`, мы также можем использовать формат
[маршрута](/doc/guide/basics.controller#route), приведенный выше. Например, предположим, что контроллер `PostController` находится в
папке `forum/controllers/admin`, тогда мы можем обратиться к действию `create` через `forum/admin/post/create`.


Вложенные модули
-------------

Модули могут быть вложенными друг в друга сколько угодно раз,
т.е. один модуль может содержать в себе другой, который
содержит в себе ещё один. Первый мы будем называть *модуль-родитель*,
второй — *модуль-потомок*.
Модули-потомки должны быть описаны в свойстве [modules|CWebModule::modules]
модуля-родителя точно так же, как мы описываем модули в файле конфигурации
приложения.

Для обращения к действию контроллера в дочернем модуле используется
маршрут `parentModuleID/childModuleID/controllerID/actionID`.